package com.googlecode.mhtetris
{
	import away3d.containers.ObjectContainer3D;
	import away3d.containers.View3D;
	import away3d.lights.DirectionalLight;
	import away3d.lights.LightBase;
	import away3d.lights.PointLight;
	import away3d.materials.ColorMaterial;
	import away3d.materials.methods.SoftShadowMapMethod;
	import away3d.primitives.Cube;
	import away3d.tools.HoverDragController;
	import away3d.tools.utils.Drag3D;
	
	import caurina.transitions.Tweener;
	
	import com.googlecode.mhtetris.music.MusicPlayer;
	import com.googlecode.mhtetris.tetris.NextBlock;
	import com.googlecode.mhtetris.tetris.Tetris3D;
	
	import flash.display.Sprite;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.events.KeyboardEvent;
	import flash.events.MouseEvent;
	import flash.geom.Vector3D;
	import flash.system.Capabilities;
	import flash.text.TextField;
	import flash.text.TextFieldAutoSize;
	import flash.text.TextFormat;
	import flash.ui.Keyboard;
	
	[SWF(frameRate="60",width="800", height="800")]
	public class Main3D extends Sprite
	{
		
		/*private var partie:Tetris3D;
		
		private var partie2:Tetris3D;*/
		
		private var tetrisArray:Array;
		
		private var next:NextBlock;
		
		private var currentFocusBlock:int = 0;
		
		private var distanceCamTetris:int = 1300;
		
		private var container:ObjectContainer3D;
		
		public static var isEmergency:Boolean = false;
		public static var isLoosing:Boolean = false;
		
		public static var score:TextField;
		
		// 3D
		private var _view : View3D;
		private var _light : DirectionalLight;
		private var _light2 : PointLight;
		private var _light3 : LightBase;
		
		public static var lights:Array;
		
		public static var shadow:SoftShadowMapMethod;
		
		private var camController : HoverDragController; // controle de caméra
		
		private var mp:MusicPlayer;
		
		
		public function Main3D()
		{
			
			
			stage.scaleMode = StageScaleMode.NO_SCALE;
			addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
			
			
			// on lance la musique
			mp = new MusicPlayer();
			mp.urlMp3 = "tetris.mp3";
			mp.load();
			mp.play();
			mp.volume(0.4);
			
			// on s'occupe de la scène 3D
			_view = new View3D;
			_view.antiAlias = 2;
			_view.x = 0;
			_view.y = 0;
			//camController = new HoverDragController(_view.camera, stage);
			/*_view.camera.rotationX = 180;
			_view.camera.z = 600;
			_view.camera.x = 150;
			_view.camera.y = 250;*/
			_view.camera.z = -distanceCamTetris;
			_view.backgroundColor = 0x888888;
			
			
			//camController.radius = 500;
			// Emergency light
			_light = new DirectionalLight(0, -50, -50); // DirectionalLight();
			_light.lookAt(new Vector3D(0,0,0));
			_light.x = 0;
			_light.y = 250;
			_light.z = 500;
			_light.specular = 5;
			_light.diffuse = 0.2;
			//			_light.radius = 2000;
			//			_light.fallOff = 3000;
			_light.color = 0xff1122;
			
			_light2 = new PointLight(); // DirectionalLight();
			_light2.x = 1250;
			_light2.y = 500;
			_light2.z = 200;
			//			_light2.radius = 2000;
			//			_light2.fallOff = 3000;
			_light2.color = 0xffffFF;
			
			_light3 = new DirectionalLight(20, 250, -80);
			_light3.x = 125;
			_light3.y = 0;
			_light3.z = 100;
			_light3.specular = 0;
			_light3.diffuse = 10;
			_light3.color = 0xffffff;
			
			/*var cube:Cube = new Cube(new ColorMaterial(0xFFFF00), 20, 20, 20);
			cube.x = _light3.x;
			cube.y = _light3.y;
			cube.z = _light3.z;
			_view.scene.addChild(cube);*/
			
			// ombre
			shadow = new SoftShadowMapMethod(_light3);
			shadow.stepSize = 5E-4;
			
			lights = [_light3, _light2, _light];
			
			_view.scene.addChild(_light);
			_view.scene.addChild(_light2);
			_view.scene.addChild(_light3);
			this.addChild(_view);
		}
		
		private function onAddedToStage(event:Event):void {
			
			// on crée le tableau de tetris
			createTetris(3);
			
			positionnerTetris();
			
			tetrisArray[0].addEventListener("blockChanged", blockChanged);
			
			next = new NextBlock((tetrisArray[0] as Tetris3D));
			next.x = Tetris3D.LARGEUR_GRILLE_PX + 40;
			_view.scene.addChild(next);
			
			score = new TextField();
			score.text = "0";
			score.selectable = false;
			var tf:TextFormat = new TextFormat("Arial", 25, 0xFFFF00, true);
			score.setTextFormat(tf);
			score.x = 550;
			score.y = 100;
			addChild(score);
			
			
			var tweenerButton:Sprite = new Sprite();
			tweenerButton.graphics.beginFill(0x45845A);
			tweenerButton.graphics.drawEllipse(0,0,100,45);
			tweenerButton.graphics.endFill();
			tweenerButton.buttonMode = true;
			tweenerButton.mouseChildren = false;
			var tef:TextField = new TextField();
			tef.text = "use tweener";
			tef.setTextFormat(new TextFormat("Arial", 15, 0xFFFFFF, true));
			tef.selectable = false;
			tef.autoSize = TextFieldAutoSize.CENTER;
			tef.x = tweenerButton.width/2 - tef.width/2;
			tef.y = tweenerButton.height/2 - tef.height/2 - 2;
			tweenerButton.addChild(tef);
			
			tweenerButton.addEventListener(MouseEvent.CLICK, switchTweener);
			
			tweenerButton.x = 550;
			tweenerButton.y = 300;
			addChild(tweenerButton);
			
			
			
			// rotate
			var rotateButton:Sprite = new Sprite();
			rotateButton.graphics.beginFill(0x45845A);
			rotateButton.graphics.drawEllipse(0,0,100,45);
			rotateButton.graphics.endFill();
			rotateButton.buttonMode = true;
			rotateButton.mouseChildren = false;
			var tf2:TextField = new TextField();
			tf2.selectable = false;
			tf2.text = "rotate light";
			tf2.autoSize = TextFieldAutoSize.CENTER;
			tf2.x = rotateButton.width/2 - tf2.width/2;
			tf2.y = rotateButton.height/2 - tf2.height/2 - 2;
			rotateButton.addChild(tf2);
			rotateButton.visible = false;
			
			rotateButton.addEventListener(MouseEvent.MOUSE_DOWN, rotateViewOk);
			rotateButton.addEventListener(MouseEvent.MOUSE_UP, rotateViewPasOk);
			
			
			rotateButton.x = 550;
			rotateButton.y = 400;
			addChild(rotateButton);
			
			this.addEventListener(Event.ENTER_FRAME, handleEnterFrame);
			
			// on ajoute la possibilité de switcher de tetris avec la touche espace
			stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
			
		}
		
		private function createTetris(nbTetris:int):void
		{
			tetrisArray = new Array();
			container = new ObjectContainer3D();
			
			for (var i:int = 0; i < nbTetris; i++) {
				var partie:Tetris3D = new Tetris3D(stage, ((Main3D) (this)));
				tetrisArray.push(partie);
				container.addChild(partie);
				//_view.scene.addChild(partie);
			}
			
			_view.scene.addChild(container);
			
			// initialise le controle des touches pour le tetris 0
			(tetrisArray[0] as Tetris3D).isListeningKeyboard = true;
		}
		
		/* dispose les tetris sous forme de cercle */
		private function positionnerTetris():void
		{
			var distance:Number = 600;
			
			var eachAngle:Number = 2*Math.PI / tetrisArray.length;
			
			for (var i:int = 0; i < tetrisArray.length; i++) {
				var tet:Tetris3D = tetrisArray[i] as Tetris3D;
				
				var newX:Number = tet.x*Math.cos(i*eachAngle) + distance*Math.sin(i*eachAngle); 
				var newZ:Number = -(-tet.x*Math.sin(i*eachAngle) + distance*Math.cos(i*eachAngle));
				
				tet.rotationY = (-i*eachAngle)*180/Math.PI;
				tet.x = newX - (Tetris3D.LARGEUR_GRILLE_PX >> 1) * Math.cos(-i*eachAngle);
				tet.z = newZ + (Tetris3D.LARGEUR_GRILLE_PX >> 1) * Math.sin(-i*eachAngle);
				tet.y = 250;
				tet.rotationX = 180;
			}
		}
		
		private function keyDownHandler(event:KeyboardEvent):void
		{
			if (event.keyCode == Keyboard.SPACE) {
				// on switche de tetris				
				(tetrisArray[currentFocusBlock] as Tetris3D).isListeningKeyboard = false;
				currentFocusBlock = (currentFocusBlock+1) % tetrisArray.length;
				rotateCam(currentFocusBlock);
				(tetrisArray[currentFocusBlock] as Tetris3D).isListeningKeyboard = true;
			}
		}
		
		/**
		 * permet le switch de tetris à celui dont l'index est indiqué par indexTetris
		 */
		private function rotateCam(indexTetris:int):void {
			/*var distance:Number = distanceCamTetris;
			var eachAngle:Number = 2*Math.PI / tetrisArray.length;
			var newX:Number = Math.cos(indexTetris*eachAngle) + distance*Math.sin(indexTetris*eachAngle); 
			var newZ:Number = -(Math.sin(indexTetris*eachAngle) + distance*Math.cos(indexTetris*eachAngle));
			
			//_view.camera.x = newX;  
			//_view.camera.z = newZ;
			Tweener.addTween(_view.camera, {
				x:newX,
				z:newZ,
				time:0.5,
				transition:"easeOutQuart",
				onUpdate: function ():void {
					_view.camera.lookAt(new Vector3D(0,0,0));					
				}
			});*/
			var eachAngle:Number = 360.0 / tetrisArray.length;
			//container.rotationY = eachAngle*indexTetris;
			
			var toRotate:Number = eachAngle*indexTetris;
			
			/*if (eachAngle*indexTetris < container.rotationY) {
				toRotate += 360;
			}*/
			
			Tweener.addTween(container, {
				rotationY:toRotate,
				time:0.5,
				transition:"easeInOutCubic",
				onStart:function():void {
					if (toRotate < container.rotationY) {
						container.rotationY -= 360;
					}
				}
			});
			
			
		}
		
		public static function getLigths():Array {
			return lights;
		}
		
		private function blockChanged(event:Event):void {
			next.gb = tetrisArray[0].nextGBlock;
		}
		
		private function switchTweener(event:MouseEvent):void {
			tetrisArray[0].USER_TWEENER = !tetrisArray[0].USER_TWEENER;
		}
		
		private function handleEnterFrame(event:Event):void {
			if (isEmergency) {
				/*if (!lights.indexOf(_light) == -1 ) {
				lights.push(_light);
				}*/
				_light.rotationY += 12;				
			} else {
				/*if (!lights.indexOf(_light) != -1 ) {
				lights.pop();
				}*/
			}
			
			if (!isLoosing) {
				_view.render();				
			} else {
				var textLoose:TextField = new TextField();
				var tf:TextFormat = new TextFormat("Arial", 72, 0xFFFF00, true);
				textLoose.autoSize = TextFieldAutoSize.CENTER;
				textLoose.text = "GAME OVER !";
				textLoose.setTextFormat(tf);
				textLoose.selectable = false;
				textLoose.x = 150;
				textLoose.y = 400;
				addChild(textLoose);
				
				this.removeEventListener(Event.ENTER_FRAME, handleEnterFrame);
			}
			
		}
		
		private function rotateViewOk(event:MouseEvent):void {
			isEmergency = !isEmergency;
		}
		
		private function rotateViewPasOk(event:MouseEvent):void {
			//isRotateLeft = false;
		}
		
	}
}